<template>
    <div>
        <!-- 面包屑导航 -->
        <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>用户管理</el-breadcrumb-item>
            <el-breadcrumb-item>用户列表</el-breadcrumb-item>
        </el-breadcrumb>

        <!-- 卡片 -->
        <el-card>
            <!-- 卡片头部 -->
            <div slot="header">
                <el-row :gutter="20">
                    <!-- 搜索用户 -->
                    <el-col :span="7">
                        <el-input placeholder="请输入用户名称" clearable v-model="queryInfo.query" @clear="getUserList">
                            <el-button slot="append" icon="el-icon-search" @click="getUserList"
                                @keyup.enter="keyDown(e)"></el-button>
                        </el-input>
                    </el-col>
                    <!-- 添加用户 -->
                    <el-col :span="6">
                        <el-button type="primary" @click="addUser()">添加用户</el-button>
                    </el-col>
                </el-row>
            </div>

            <!-- 卡片主体 -->
            <div>
                <!-- 用户列表 -->
                <el-table :data="userList" :default-sort="{ prop: 'create_time', order: 'descending' }">
                    <el-table-column type="index" label="编号" align="center"></el-table-column>
                    <el-table-column prop="username" label="用户名称" align="center"></el-table-column>
                    <el-table-column prop="role_name" label="角色名称" align="center"></el-table-column>
                    <el-table-column prop="mobile" label="手机号码" align="center"></el-table-column>
                    <el-table-column prop="email" label="邮箱" align="center"></el-table-column>
                    <el-table-column label="状态" align="center" width="80">
                        <template slot-scope="scope">
                            <el-switch v-model="scope.row.mg_state" @change="userStateChange(scope.row)"></el-switch>
                        </template>
                    </el-table-column>
                    <el-table-column prop="create_time" label="创建时间" align="center" sortable width="180">
                        <template slot-scope="scope">
                            {{ scope.row.create_time | dateFormat('yyyy-MM-dd hh: mm: ss') }}
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" align="center" width="249">
                        <template slot-scope="scope">
                            <el-button size="mini" type="primary" @click="editUser(scope.row.id)">
                                编辑
                            </el-button>
                            <el-button size="mini" type="danger" @click="deleteUser(scope.row.id, scope.row.username)">
                                删除
                            </el-button>
                            <el-button size="mini" type="warning" @click="setRolesDialog(scope.row)">
                                分配角色
                            </el-button>
                        </template>
                    </el-table-column>
                </el-table>

                <!-- 分页 -->
                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                    :current-page="queryInfo.pagenum" :page-sizes="[1, 2, 10, 20]" :page-size="queryInfo.pagesize"
                    layout="total, sizes, prev, pager, next, jumper" :total="userTotal" background>
                </el-pagination>
            </div>
        </el-card>

        <!-- 添加用户对话框 -->
        <el-dialog :title="addUserDialogTitle" :visible.sync="addUserDialogVisible" width="30%"
            :close-on-click-modal="false" @close="addUserDialogClose">
            <el-form :model="addUserFormData" :rules="addUserFormRules" ref="addUserFormRef" label-width="100px"
                status-icon>
                <el-form-item label="用户名称" prop="username">
                    <el-input v-model="addUserFormData.username"></el-input>
                </el-form-item>
                <el-form-item label="用户密码" prop="password">
                    <el-input type="password" v-model="addUserFormData.password">
                    </el-input>
                </el-form-item>
                <el-form-item label="邮箱" prop="email">
                    <el-input v-model="addUserFormData.email"></el-input>
                </el-form-item>
                <el-form-item label="手机号" prop="mobile">
                    <el-input v-model="addUserFormData.mobile"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer">
                <el-button @click="addUserDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="addUserSubmit()">确 定</el-button>
            </span>
        </el-dialog>

        <!-- 编辑用户对话框 -->
        <el-dialog :title="editUserDialogTitle" :visible.sync="editUserDialogVisible" width="30%"
            :close-on-click-modal="false" @close="editUserDialogClose">
            <el-form :model="editUserFormData" :rules="editUserFormRules" ref="editUserFormRef" label-width="100px"
                status-icon>
                <el-form-item label="用户名称" prop="username">
                    <el-input v-model="editUserFormData.username" disabled></el-input>
                </el-form-item>
                <el-form-item label="邮箱" prop="email">
                    <el-input v-model="editUserFormData.email"></el-input>
                </el-form-item>
                <el-form-item label="手机号" prop="mobile">
                    <el-input v-model="editUserFormData.mobile"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer">
                <el-button @click="editUserDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="editUserSubmit()">确 定</el-button>
            </span>
        </el-dialog>

        <!-- 分配角色对话框 -->
        <el-dialog title="分配角色" :visible.sync="setRolesDialogVisible" width="30%" :close-on-click-modal="false"
            @close="setRolesDialogClose">
            <el-descriptions direction="vertical">
                <el-descriptions-item label="用户名称">
                    <el-tag>{{ this.userInfo.username }}</el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="当前角色">
                    <el-tag>{{ this.userInfo.role_name }}</el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="分配新角色">
                    <el-select v-model="selectdRoleId" placeholder="请选择新角色">
                        <el-option v-for="item in roleList" :key="item.id" :label="item.roleName" :value="item.id">
                        </el-option>
                    </el-select>
                </el-descriptions-item>
            </el-descriptions>
            <span slot="footer">
                <el-button @click="setRolesDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="setRolesSubmit()">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
export default {
    data() {
        // 自定义表单验证规则
        // 邮箱验证
        var checkEmail = (rule, value, callback) => {
            const regEmail = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/;
            if (regEmail.test(value)) return callback();
            callback(new Error('请输入正确的邮箱格式'));
        };
        // 手机号验证
        var checkMobile = (rule, value, callback) => {
            const regMobile = /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/;
            if (regMobile.test(value)) return callback();
            callback(new Error('请输入正确的手机号格式'));
        };
        // 用户是否存在验证
        var checkUser = async (rule, value, callback) => {
            // 判断用户名是否已存在
            const { data: res } = await this.$http.get('users', {
                params: {
                    query: value,
                    pagenum: 1,
                    pagesize: 1
                }
            });
            // 用户已存在
            if (res.data.total !== 0) return callback(new Error('该用户已存在'));
            callback();
        };
        return {
            // 查询用户列表数据所需参数
            queryInfo: {
                query: '', // 查询参数
                pagenum: 1, // 当前页码
                pagesize: 2 // 每页显示条数
            },
            // 用户列表数据
            userList: [],
            // 用户列表数据总记录数
            userTotal: 0,
            // 添加用户对话框的显示与隐藏
            addUserDialogVisible: false,
            // 编辑用户对话框的显示与隐藏
            editUserDialogVisible: false,
            // 添加用户对话框的标题
            addUserDialogTitle: '添加用户',
            // 编辑用户对话框的标题
            editUserDialogTitle: '编辑用户',
            // 添加用户的表单数据对象
            addUserFormData: {
                username: '',
                password: '',
                email: '',
                mobile: ''
            },
            // 编辑用户的表单数据对象(根据id查询到的数据也存在这,所以可以不用写参数)
            editUserFormData: {
                // id: '',
                // username: '',
                // email: '',
                // mobile: ''
            },
            // 添加用户的表单规则验证对象
            addUserFormRules: {
                username: [
                    { required: true, message: '请输入用户名称', trigger: 'blur' },
                    { min: 2, max: 11, message: '长度在2到11个字符' },
                    { pattern: /^[^\s]*$/, message: '禁止输入空格', trigger: 'blur' },
                    { validator: checkUser, trigger: 'blur' }
                ],
                password: [
                    { required: true, message: '请输入用户密码', trigger: 'blur' },
                    { min: 6, max: 15, message: '长度在6到15个字符' },
                    { pattern: /^[^\s]*$/, message: '禁止输入空格', trigger: 'blur' }

                ],
                email: [
                    { required: true, message: '请输入邮箱', trigger: 'blur' },
                    { pattern: /^[^\s]*$/, message: '禁止输入空格', trigger: 'blur' },
                    { validator: checkEmail, trigger: 'blur' }
                ],
                mobile: [
                    { required: true, message: '请输入手机号', trigger: 'blur' },
                    { pattern: /^[^\s]*$/, message: '禁止输入空格', trigger: 'blur' },
                    { validator: checkMobile, trigger: 'blur' }
                ]
            },
            // 编辑用户的表单规则验证对象
            editUserFormRules: {
                username: [
                    { required: true, message: '请输入用户名称', trigger: 'blur' },
                    { min: 2, max: 11, message: '长度在2到11个字符' },
                    { pattern: /^[^\s]*$/, message: '禁止输入空格', trigger: 'blur' }
                ],
                email: [
                    { required: true, message: '请输入邮箱', trigger: 'blur' },
                    { pattern: /^[^\s]*$/, message: '禁止输入空格', trigger: 'blur' },
                    { validator: checkEmail, trigger: 'blur' }
                ],
                mobile: [
                    { required: true, message: '请输入手机号', trigger: 'blur' },
                    { pattern: /^[^\s]*$/, message: '禁止输入空格', trigger: 'blur' },
                    { validator: checkMobile, trigger: 'blur' }
                ]
            },
            // 分配角色的对话框
            setRolesDialogVisible: false,
            // 用户信息
            userInfo: {},
            // 选中的角色id
            selectdRoleId: '',
            // 角色列表
            roleList: []
        }
    },
    created() {
        // 获取用户列表数据
        this.getUserList();
    },
    methods: {
        // 获取用户列表
        async getUserList() {
            const { data: res } = await this.$http.get('users', { params: this.queryInfo });
            if (res.meta.status !== 200) return this.$message, error('获取用户列表失败！')
            this.userList = res.data.users;
            this.userTotal = res.data.total;
        },
        // 处理每页显示条数的变化
        handleSizeChange(val) {
            this.queryInfo.pagesize = val;
            this.getUserList();
        },
        // 处理当前页码的变化
        handleCurrentChange(val) {
            this.queryInfo.pagenum = val;
            this.getUserList();
        },
        // 用户状态改变
        async userStateChange(userInfo) {
            if (userInfo.mg_state === false) {
                this.$confirm(`确认要停用"${userInfo.username}"用户吗？`, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    closeOnClickModal: false, // 点击空白处不关闭弹框
                    type: 'warning'
                }).then(async () => {
                    const { data: res } = await this.$http.put(`users/${userInfo.id}/state/${userInfo.mg_state}`);
                    if (res.meta.status !== 200) {
                        userInfo.mg_state = !userInfo.mg_state;
                        return this.$message.error('用户状态更新失败！');
                    }
                    this.$message({
                        type: 'success',
                        message: '停用成功！'
                    });
                }).catch(() => {
                    userInfo.mg_state = true;
                    this.$message({
                        type: 'info',
                        message: '已取消停用'
                    });
                });
            } else {
                const { data: res } = await this.$http.put(`users/${userInfo.id}/state/${userInfo.mg_state}`);
                if (res.meta.status !== 200) {
                    userInfo.mg_state = !userInfo.mg_state;
                    return this.$message.error('用户状态更新失败！');
                }
            }
        },
        // 点击 添加用户 按钮事件
        addUser() {
            // 显示对话框
            this.addUserDialogVisible = true;
        },
        // 点击 编辑用户 按钮事件
        editUser(userId) {
            // 显示对话框
            this.editUserDialogVisible = true;
            // 回写编辑用户对话框的数据
            this.writeBackUserInfo(userId);
            // 将用户id存储在data中,用于确认 编辑用户 使用
            this.enterEditUserId = userId;
        },
        // 根据id查询并回写编辑用户对话框的数据
        async writeBackUserInfo(userId) {
            const { data: res } = await this.$http.get(`users/${userId}`);
            if (res.meta.status !== 200) return this.$message.error('用户信息获取失败');
            this.editUserFormData = res.data;
        },
        // 添加用户对话框的关闭事件
        addUserDialogClose() {
            // 对整个表单进行重置，将所有字段值重置为初始值并移除校验结果
            this.$refs.addUserFormRef.resetFields();
        },
        // 编辑用户对话框的关闭事件
        editUserDialogClose() {
            // 对整个表单进行重置，将所有字段值重置为初始值并移除校验结果
            this.$refs.editUserFormRef.resetFields();
        },
        // 确定 添加用户
        addUserSubmit() {
            // 对整个表单进行校验
            this.$refs.addUserFormRef.validate(async valid => {
                if (valid) {
                    // 验证通过
                    const { data: res } = await this.$http.post('users', this.addUserFormData);
                    if (res.meta.status !== 201)
                        return this.$notify.error({
                            title: '用户创建失败',
                            message: '您可联系网站作者进行解决   www.h1234.top',
                            duration: 5000
                        });
                    this.$message.success('用户创建成功');
                    // 重新获取用户列表数据
                    this.getUserList();
                    // 隐藏对话框
                    this.addUserDialogVisible = false;
                }
            });
        },
        // 确定 编辑用户
        editUserSubmit() {
            // 对整个表单进行校验
            this.$refs.editUserFormRef.validate(async valid => {
                if (valid) {
                    // 验证通过
                    const { data: res } = await this.$http.put(`users/${this.editUserFormData.id}`, {
                        email: this.editUserFormData.email,
                        mobile: this.editUserFormData.mobile
                    });
                    if (res.meta.status !== 200)
                        return this.$notify.error({
                            title: '用户信息修改失败',
                            message: '您可联系网站作者进行解决   www.h1234.top',
                            duration: 5000
                        });
                    this.$message.success('用户信息修改成功');
                    // 重新获取用户列表数据
                    this.getUserList();
                    this.editUserDialogVisible = false;
                }
            });
        },
        // 删除用户
        deleteUser(userId, username) {
            this.$confirm(`此操作将永久删除 '${username}' 用户, 是否继续?`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'error'
            }).then(async () => {
                const { data: res } = await this.$http.delete('users/' + userId);
                if (res.meta.status !== 200) return this.$message.error('删除失败');
                this.$message({
                    type: 'success',
                    message: '删除成功!'
                });
                // 重新获取用户列表
                this.getUserList();
            }).catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });
            });
        },
        // 回车键搜索
        keyDown(e) {
            //如果是回车则执行搜索方法
            if (e.keyCode == 13) {
                this.getUserList();
            }
        },
        // 控制分配角色对话框的显示与隐藏
        setRolesDialog(userInfo) {
            // 显示分配角色对话框
            this.setRolesDialogVisible = true;
            this.userInfo = userInfo;
            // 获取角色列表
            this.getRolesList();
        },
        // 获取角色列表
        async getRolesList() {
            const { data: res } = await this.$http.get('roles');
            if (res.meta.status !== 200) return this.$message.error('角色列表获取失败');
            this.roleList = res.data;
        },
        // 确定提交 分配角色
        async setRolesSubmit() {
            if (!this.selectdRoleId) {
                // 未选中角色
                this.$message.info('请选择新角色')
            } else {
                const { data: res } = await this.$http.put(`users/${this.userInfo.id}/role`, {
                    rid: this.selectdRoleId
                });
                if (res.meta.status !== 200) return this.$message.error('分配角色失败');
                this.$message.success('分配角色成功');
                this.getUserList();
                this.setRolesDialogVisible = false;
            }
        },
        // 监听分配角色对话框关闭事件
        setRolesDialogClose() {
            this.selectdRoleId = '';
        }
    },
    // 回车键搜索 绑定监听事件
    mounted() {
        window.addEventListener('keydown', this.keyDown);
    },
    // 回车键搜索 摧毁事件
    destroyed() {
        window.removeEventListener('keydown', this.keyDown, false);
    }
}
</script>

<style lang="less" scoped>
</style>
